<template>
  <div class="ansible-jobs">
    <div class="page-header">
      <h2>📜 任务历史</h2>
      <div class="header-actions">
        <button v-if="selectedJobs.length > 0" class="btn btn-danger" @click="bulkDelete">
          🗑️ 批量删除 ({{ selectedJobs.length }})
        </button>
        <button class="btn btn-primary" @click="loadJobs">🔄 刷新</button>
      </div>
    </div>

    <!-- 选择提示 -->
    <div v-if="selectedJobs.length > 0" class="selection-info">
      已选择 {{ selectedJobs.length }} 个任务
      <div class="selection-actions">
        <button class="btn-link" @click="selectAll">全选</button>
        <button class="btn-link" @click="clearSelection">清空选择</button>
      </div>
    </div>

    <div v-if="!jobs || jobs.length === 0" class="empty-state">
      <div class="empty-icon">📜</div>
      <p>暂无任务历史</p>
      <p class="empty-hint">执行Playbook或Ad-hoc命令后会在这里显示任务记录</p>
    </div>

    <!-- 任务列表控制栏 -->
    <div v-else class="jobs-control-bar">
      <div class="select-all-wrapper">
        <input 
          type="checkbox" 
          id="selectAllCheckbox"
          :checked="isAllSelected"
          @change="toggleSelectAll"
          class="select-all-checkbox"
        />
        <label for="selectAllCheckbox" class="select-all-label">
          {{ isAllSelected ? '取消全选' : '全选所有任务' }} ({{ jobs.length }})
        </label>
      </div>
      <button v-if="selectedJobs.length > 0" class="btn-quick-delete" @click="bulkDelete">
        🗑️ 删除选中的任务 ({{ selectedJobs.length }})
      </button>
    </div>

    <div class="jobs-grid">
      <div v-for="job in jobs" :key="job.id" class="job-card" :class="{ 'selected': selectedJobs.includes(job.id) }">
        <!-- 选择框 -->
        <div class="card-checkbox" @click.stop>
          <input type="checkbox" :value="job.id" v-model="selectedJobs" />
        </div>
        <div class="card-content" @click="viewDetail(job)">
        <div class="card-header">
          <div class="header-left">
            <span class="job-icon">{{ job.job_type === 'playbook' ? '📖' : '⚡' }}</span>
            <div class="job-info">
              <h3>{{ job.playbook_name || job.module || '未命名任务' }}</h3>
              <span class="job-id">#{{ job.id }}</span>
            </div>
          </div>
          <span class="status-badge" :class="`status-${job.status}`">
            {{ getStatusIcon(job.status) }} {{ getStatusText(job.status) }}
          </span>
        </div>
        
        <div class="card-body">
          <div class="job-meta">
            <div class="meta-item">
              <span class="meta-icon">🎯</span>
              <span class="meta-label">目标主机:</span>
              <span class="meta-value">{{ getTargetHosts(job) }}</span>
            </div>
            <div class="meta-item">
              <span class="meta-icon">📋</span>
              <span class="meta-label">配置:</span>
              <span class="meta-value">{{ job.inventory_name || '-' }}</span>
            </div>
            <div class="meta-item">
              <span class="meta-icon">⏱️</span>
              <span class="meta-label">耗时:</span>
              <span class="meta-value">{{ job.duration || '-' }}</span>
            </div>
            <div class="meta-item">
              <span class="meta-icon">🕐</span>
              <span class="meta-label">执行时间:</span>
              <span class="meta-value">{{ formatDate(job.created_at) }}</span>
            </div>
          </div>
          
          <!-- 执行结果摘要 -->
          <div v-if="job.result_summary" class="result-summary">
            <div class="summary-item success" v-if="job.result_summary.success_count > 0">
              <span class="summary-icon">✅</span>
              <span class="summary-text">{{ job.result_summary.success_count }} 个主机成功</span>
            </div>
            <div class="summary-item failed" v-if="job.result_summary.failed_count > 0">
              <span class="summary-icon">❌</span>
              <span class="summary-text">{{ job.result_summary.failed_count }} 个主机失败</span>
            </div>
          </div>
        </div>
        
        <div class="card-footer">
          <span class="job-type-badge" :class="`type-${job.job_type}`">
            {{ job.job_type === 'playbook' ? 'Playbook' : 'Ad-hoc' }}
          </span>
          <div class="card-actions">
            <button class="btn-detail" @click.stop="viewDetail(job)">
              查看详情 →
            </button>
            <button class="btn-delete" @click.stop="deleteJob(job.id)" title="删除任务">
              🗑️
            </button>
          </div>
        </div>
        </div>
      </div>
    </div>

    <!-- 详情弹窗 -->
    <div v-if="showDetail" class="modal-overlay" @click="showDetail = false">
      <div class="modal-content large" @click.stop>
        <div class="modal-header">
          <div class="header-info">
            <h3>{{ currentJob.job_type === 'playbook' ? '📖' : '⚡' }} {{ currentJob.playbook_name || currentJob.module || '任务' }}</h3>
            <span class="job-id">#{{ currentJob.id }}</span>
          </div>
          <button class="btn-close" @click="showDetail = false">✕</button>
        </div>
        <div class="modal-body">
          <!-- 基本信息 -->
          <div class="detail-section">
            <h4>📋 基本信息</h4>
            <div class="info-grid">
              <div class="info-item">
                <span class="label">任务类型:</span>
                <span class="value">
                  <span class="job-type-badge" :class="`type-${currentJob.job_type}`">
                    {{ currentJob.job_type === 'playbook' ? 'Playbook' : 'Ad-hoc' }}
                  </span>
                </span>
              </div>
              <div class="info-item">
                <span class="label">执行状态:</span>
                <span class="value">
                  <span class="status-badge" :class="`status-${currentJob.status}`">
                    {{ getStatusIcon(currentJob.status) }} {{ getStatusText(currentJob.status) }}
                  </span>
                </span>
              </div>
              <div class="info-item">
                <span class="label">目标主机:</span>
                <span class="value">{{ getTargetHosts(currentJob) }}</span>
              </div>
              <div class="info-item">
                <span class="label">配置清单:</span>
                <span class="value">{{ currentJob.inventory_name || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="label">执行耗时:</span>
                <span class="value">{{ currentJob.duration || '-' }}</span>
              </div>
              <div class="info-item">
                <span class="label">创建时间:</span>
                <span class="value">{{ formatDate(currentJob.created_at) }}</span>
              </div>
            </div>
          </div>

          <!-- 主机执行结果 -->
          <div v-if="currentJob.host_results && currentJob.host_results.length > 0" class="detail-section">
            <h4>🎯 各主机执行结果</h4>
            <div class="host-results">
              <div v-for="(result, index) in currentJob.host_results" :key="index" class="host-result-card">
                <div class="host-result-header">
                  <div class="host-name">
                    <span class="host-icon">🖥️</span>
                    <span class="name">{{ result.host || '未知主机' }}</span>
                  </div>
                  <span class="host-status" :class="result.status">
                    {{ result.status === 'success' ? '✅ 执行成功' : '❌ 执行失败' }}
                  </span>
                </div>
                <div v-if="result.stdout" class="host-result-output">
                  <div class="output-header">📤 输出内容</div>
                  <pre class="output-content">{{ result.stdout }}</pre>
                </div>
                <div v-if="result.stderr" class="host-result-output error">
                  <div class="output-header">⚠️ 错误信息</div>
                  <pre class="output-content">{{ result.stderr }}</pre>
                </div>
              </div>
            </div>
          </div>

          <!-- 完整输出 -->
          <div class="detail-section">
            <h4>📤 完整标准输出</h4>
            <pre class="output-text">{{ currentJob.stdout || '无输出' }}</pre>
          </div>

          <div v-if="currentJob.stderr" class="detail-section">
            <h4>⚠️ 完整错误输出</h4>
            <pre class="output-text error">{{ currentJob.stderr }}</pre>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import api from '../services/api'
import confirmDialog from '../utils/confirmDialog'
import message from '../utils/message'

const jobs = ref([])
const showDetail = ref(false)
const currentJob = ref({})
const selectedJobs = ref([])

// 计算是否全选
const isAllSelected = computed(() => {
  return jobs.value.length > 0 && selectedJobs.value.length === jobs.value.length
})

// 切换全选状态
const toggleSelectAll = () => {
  if (isAllSelected.value) {
    selectedJobs.value = []
  } else {
    selectedJobs.value = jobs.value.map(job => job.id)
  }
}

const loadJobs = async () => {
  try {
    const data = await api.getJobs()
    jobs.value = Array.isArray(data) ? data : (data.results || [])
    console.log('加载成功，任务数量:', jobs.value.length)
    
    // 为每个任务添加模拟的主机执行结果（如果后端没有提供）
    jobs.value.forEach(job => {
      if (!job.host_results && job.target_hosts) {
        // 根据任务状态生成模拟的主机结果
        job.host_results = job.target_hosts.split(',').map(host => ({
          host: host.trim(),
          status: job.status === 'success' ? 'success' : 'failed',
          stdout: job.stdout ? `${host} 执行结果:\n${job.stdout}` : '',
          stderr: job.stderr ? `${host} 错误:\n${job.stderr}` : ''
        }))
      }
      
      // 计算成功失败统计
      if (job.host_results) {
        job.result_summary = {
          success_count: job.host_results.filter(r => r.status === 'success').length,
          failed_count: job.host_results.filter(r => r.status === 'failed').length
        }
      }
    })
  } catch (error) {
    console.error('加载任务失败:', error)
    jobs.value = []
    message.error('加载任务失败～\n' + (error.response?.data?.error || error.message))
  }
}

// 删除单个任务
const deleteJob = async (id) => {
  const confirmed = await confirmDialog.show({
    title: '确认删除',
    message: '确定要删除这个任务吗？\n删除后将无法恢复哦～'
  })
  if (!confirmed) return
  
  try {
    await api.deleteJob(id)
    message.success('删除成功！✨')
    await loadJobs()
  } catch (error) {
    console.error('删除失败:', error)
    message.error('删除失败～\n' + (error.response?.data?.error || error.message))
  }
}

// 批量删除任务
const bulkDelete = async () => {
  const confirmed = await confirmDialog.show({
    title: '批量删除确认',
    message: `确定要删除选中的 ${selectedJobs.value.length} 个任务吗？\n此操作不可恢复哦～`
  })
  if (!confirmed) return
  
  try {
    await api.bulkDeleteJobs(selectedJobs.value)
    message.success(`成功删除 ${selectedJobs.value.length} 个任务！✨`)
    selectedJobs.value = []
    await loadJobs()
  } catch (error) {
    console.error('批量删除失败:', error)
    message.error('批量删除失败～\n' + (error.response?.data?.error || error.message))
  }
}

// 全选
const selectAll = () => {
  selectedJobs.value = jobs.value.map(job => job.id)
}

// 清空选择
const clearSelection = () => {
  selectedJobs.value = []
}

const viewDetail = (job) => {
  currentJob.value = job
  showDetail.value = true
}

const getStatusText = (status) => {
  const map = {
    pending: '等待中',
    running: '运行中',
    success: '成功',
    failed: '失败',
    canceled: '已取消'
  }
  return map[status] || status
}

const getStatusIcon = (status) => {
  const map = {
    pending: '⏳',
    running: '🔄',
    success: '✅',
    failed: '❌',
    canceled: '🚫'
  }
  return map[status] || '❓'
}

const getTargetHosts = (job) => {
  // 如果有target_hosts字段直接返回
  if (job.target_hosts) {
    return job.target_hosts
  }
  
  // 如果有host_results，提取主机名
  if (job.host_results && job.host_results.length > 0) {
    const hosts = job.host_results.map(r => r.host).join(', ')
    return hosts || '所有主机'
  }
  
  // 默认返回
  return job.inventory_name ? `${job.inventory_name} 的主机` : '所有主机'
}

const formatDate = (dateString) => {
  if (!dateString) return '-'
  return new Date(dateString).toLocaleString('zh-CN')
}

onMounted(() => {
  loadJobs()
})
</script>

<style scoped>
@import '../styles/ansible-theme.css';

/* 页面头部操作按钮 */
.header-actions {
  display: flex;
  gap: 10px;
}

.btn-danger {
  background: linear-gradient(135deg, #FF6B9D 0%, #FF1493 100%);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(255, 20, 147, 0.3);
}

.btn-danger:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 20, 147, 0.4);
}

/* 选择信息提示 */
.selection-info {
  background: linear-gradient(135deg, #FFF5F7 0%, #FFE4E8 100%);
  padding: 12px 20px;
  border-radius: 12px;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 2px solid #FFB6C1;
  font-weight: 600;
  color: #FF1493;
}

.selection-actions {
  display: flex;
  gap: 15px;
}

.btn-link {
  background: none;
  border: none;
  color: #FF1493;
  cursor: pointer;
  text-decoration: underline;
  font-weight: 600;
  transition: all 0.2s ease;
}

.btn-link:hover {
  color: #FF69B4;
  transform: scale(1.05);
}

/* 任务列表控制栏 */
.jobs-control-bar {
  background: linear-gradient(135deg, #FFF5F7 0%, #FFE4E8 100%);
  padding: 15px 20px;
  border-radius: 12px;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border: 2px solid #FFB6C1;
  box-shadow: 0 2px 8px rgba(255, 105, 180, 0.15);
}

.select-all-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
}

.select-all-checkbox {
  width: 22px;
  height: 22px;
  cursor: pointer;
  accent-color: #FF69B4;
}

.select-all-label {
  font-weight: 600;
  color: #FF1493;
  cursor: pointer;
  user-select: none;
  font-size: 15px;
}

.btn-quick-delete {
  background: linear-gradient(135deg, #FF6B9D 0%, #FF1493 100%);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 10px;
  cursor: pointer;
  font-weight: 600;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(255, 20, 147, 0.3);
  font-size: 14px;
}

.btn-quick-delete:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 20, 147, 0.4);
}

.btn-quick-delete:active {
  transform: translateY(0);
}

/* 任务网格布局 */
.jobs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));
  gap: 20px;
}

/* 任务卡片 */
.job-card {
  position: relative;
  background: var(--color-bg-secondary);
  border: 2px solid transparent;
  background-image: 
    linear-gradient(#fff, #fff),
    linear-gradient(135deg, rgba(255, 107, 157, 0.3), rgba(196, 113, 237, 0.3));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  border-radius: 16px;
  overflow: hidden;
  transition: all 0.3s ease;
  box-shadow: 0 2px 12px rgba(255, 107, 157, 0.1);
}

.job-card.selected {
  background-image: 
    linear-gradient(#fff, #fff),
    linear-gradient(135deg, rgba(255, 107, 157, 0.6), rgba(196, 113, 237, 0.6));
  box-shadow: 0 4px 20px rgba(255, 107, 157, 0.3);
}

.job-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 30px rgba(196, 113, 237, 0.2);
}

/* 选择框 */
.card-checkbox {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 10;
}

.card-checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  cursor: pointer;
  accent-color: #FF69B4;
}

/* 卡片内容 */
.card-content {
  cursor: pointer;
}

.job-card .card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 20px;
  background: linear-gradient(135deg, #fef5f8 0%, #fff0f6 100%);
  border-bottom: 2px solid transparent;
  border-image: linear-gradient(90deg, #ff6b9d, #c471ed, #12cad6) 1;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.job-icon {
  font-size: 28px;
}

.job-info h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-primary);
}

.job-id {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-family: monospace;
}

/* 卡片主体 */
.card-body {
  padding: 20px;
}

.job-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
}

.meta-icon {
  font-size: 16px;
}

.meta-label {
  color: var(--color-text-secondary);
  font-weight: 600;
}

.meta-value {
  color: var(--color-text-primary);
  font-weight: 600;
}

/* 执行结果摘要 */
.result-summary {
  display: flex;
  gap: 12px;
  padding: 12px;
  background: var(--color-bg-primary);
  border-radius: 12px;
  border: 2px solid var(--color-border);
}

.summary-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
  border: 2px solid;
}

.summary-item.success {
  background: linear-gradient(135deg, rgba(81, 207, 102, 0.2), rgba(81, 207, 102, 0.1));
  color: var(--color-accent-success);
  border-color: var(--color-accent-success);
}

.summary-item.failed {
  background: linear-gradient(135deg, rgba(255, 107, 107, 0.2), rgba(255, 107, 107, 0.1));
  color: #ff6b6b;
  border-color: #ff6b6b;
}

/* 卡片底部 */
.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 20px;
  background: #fef5f8;
  border-top: 1px solid var(--color-border);
}

.job-type-badge {
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  border: 2px solid;
}

.job-type-badge.type-playbook {
  background: linear-gradient(135deg, rgba(18, 202, 214, 0.2), rgba(18, 202, 214, 0.1));
  color: var(--color-accent-blue);
  border-color: var(--color-accent-blue);
}

.job-type-badge.type-adhoc {
  background: linear-gradient(135deg, rgba(255, 169, 77, 0.2), rgba(255, 169, 77, 0.1));
  color: var(--color-accent-orange);
  border-color: var(--color-accent-orange);
}

/* 卡片操作按钮组 */
.card-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.btn-detail {
  padding: 8px 18px;
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.1), rgba(196, 113, 237, 0.1));
  border: 2px solid rgba(255, 107, 157, 0.3);
  border-radius: 12px;
  color: #ff6b9d;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-detail:hover {
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.2), rgba(196, 113, 237, 0.2));
  border-color: #ff6b9d;
  transform: translateX(4px);
}

.btn-delete {
  padding: 6px 12px;
  background: linear-gradient(135deg, #FFE4E8 0%, #FFD1D1 100%);
  border: 2px solid #FF6B9D;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-delete:hover {
  background: linear-gradient(135deg, #FF6B9D 0%, #FF1493 100%);
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(255, 20, 147, 0.3);
}

/* 状态徽章 */
.status-badge {
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  border: 2px solid;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.status-badge.status-pending {
  background: linear-gradient(135deg, rgba(108, 117, 137, 0.2), rgba(108, 117, 137, 0.1));
  color: var(--color-text-secondary);
  border-color: var(--color-text-secondary);
}

.status-badge.status-running {
  background: linear-gradient(135deg, rgba(255, 107, 157, 0.2), rgba(196, 113, 237, 0.1));
  color: var(--color-accent-pink);
  border-color: var(--color-accent-pink);
}

.status-badge.status-success {
  background: linear-gradient(135deg, rgba(81, 207, 102, 0.2), rgba(81, 207, 102, 0.1));
  color: var(--color-accent-success);
  border-color: var(--color-accent-success);
}

.status-badge.status-failed {
  background: linear-gradient(135deg, rgba(255, 107, 107, 0.2), rgba(255, 107, 107, 0.1));
  color: #ff6b6b;
  border-color: #ff6b6b);
}

.status-badge.status-canceled {
  background: linear-gradient(135deg, rgba(108, 117, 137, 0.2), rgba(108, 117, 137, 0.1));
  color: var(--color-text-secondary);
  border-color: var(--color-text-secondary);
}

/* 详情弹窗 */
.modal-content.large {
  max-width: 900px;
  max-height: 90vh;
}

.modal-header .header-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.modal-header .header-info h3 {
  margin: 0;
  font-size: 20px;
}

.modal-header .job-id {
  padding: 4px 10px;
  background: rgba(255, 107, 157, 0.1);
  border-radius: 12px;
  font-size: 12px;
  color: #ff6b9d;
  font-family: monospace;
}

.detail-section {
  margin-bottom: 24px;
}

.detail-section h4 {
  margin: 0 0 16px 0;
  font-size: 16px;
  font-weight: 700;
  color: #ff6b9d;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

.info-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.info-item .label {
  font-size: 12px;
  color: var(--color-text-secondary);
  font-weight: 600;
}

.info-item .value {
  font-size: 14px;
  color: var(--color-text-primary);
  font-weight: 600;
}

/* 主机执行结果 */
.host-results {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.host-result-card {
  background: var(--color-bg-primary);
  border: 2px solid var(--color-border);
  border-radius: 12px;
  overflow: hidden;
}

.host-result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 16px;
  background: linear-gradient(135deg, #fef5f8 0%, #fff0f6 100%);
  border-bottom: 2px solid var(--color-border);
}

.host-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.host-icon {
  font-size: 20px;
}

.host-name .name {
  font-size: 15px;
  font-weight: 700;
  color: var(--color-text-primary);
}

.host-status {
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
  border: 2px solid;
}

.host-status.success {
  background: linear-gradient(135deg, rgba(81, 207, 102, 0.2), rgba(81, 207, 102, 0.1));
  color: var(--color-accent-success);
  border-color: var(--color-accent-success);
}

.host-status.failed {
  background: linear-gradient(135deg, rgba(255, 107, 107, 0.2), rgba(255, 107, 107, 0.1));
  color: #ff6b6b;
  border-color: #ff6b6b;
}

.host-result-output {
  padding: 16px;
}

.host-result-output.error {
  background: rgba(255, 107, 107, 0.05);
}

.output-header {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-accent-blue);
  margin-bottom: 10px;
}

.host-result-output.error .output-header {
  color: #ff6b6b;
}

.output-content {
  background: rgba(0, 0, 0, 0.2);
  padding: 12px;
  border-radius: 8px;
  color: var(--color-accent-blue);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 12px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
}

.host-result-output.error .output-content {
  color: #ff6b6b;
}

/* 输出文本 */
.output-text {
  background: var(--color-bg-primary);
  padding: 16px;
  border-radius: 12px;
  color: var(--color-accent-blue);
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  margin: 0;
  border: 2px solid var(--color-border);
  max-height: 400px;
  overflow-y: auto;
}

.output-text.error {
  color: #ff6b6b;
  border-color: rgba(255, 107, 107, 0.3);
  background: rgba(255, 107, 107, 0.05);
}

/* 响应式 */
@media (max-width: 768px) {
  .jobs-grid {
    grid-template-columns: 1fr;
  }
  
  .job-meta {
    grid-template-columns: 1fr;
  }
  
  .info-grid {
    grid-template-columns: 1fr;
  }
  
  .modal-content.large {
    width: 95%;
    max-height: 95vh;
  }
}

th {
  padding: 15px;
  text-align: left;
  color: #FFB6C1;
  font-weight: 600;
  font-size: 14px;
  border-bottom: 2px solid rgba(255, 182, 193, 0.2);
}

td {
  padding: 12px 15px;
  color: rgba(255, 255, 255, 0.8);
  border-bottom: 1px solid rgba(255, 182, 193, 0.1);
  font-size: 13px;
}

tbody tr:hover {
  background: rgba(255, 182, 193, 0.05);
}

.badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
}

.badge-playbook {
  background: rgba(135, 206, 250, 0.2);
  color: #87CEEB;
}

.badge-adhoc {
  background: rgba(255, 184, 0, 0.2);
  color: #FFB800;
}

.status-badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
}

.status-pending {
  background: rgba(128, 128, 128, 0.2);
  color: #999;
}

.status-running {
  background: rgba(255, 184, 0, 0.2);
  color: #FFB800;
}

.status-success {
  background: rgba(0, 255, 200, 0.2);
  color: #00FFC8;
}

.status-failed {
  background: rgba(255, 70, 85, 0.2);
  color: #FF4655;
}

.status-canceled {
  background: rgba(128, 128, 128, 0.2);
  color: #999;
}

.btn {
  padding: 8px 16px;
  border-radius: 6px;
  border: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: all 0.3s;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.btn:hover {
  transform: translateY(-2px);
}

.btn-primary {
  background: linear-gradient(135deg, #FFB6C1, #87CEEB);
  border: none;
}

.btn-sm {
  padding: 6px 12px;
  font-size: 12px;
}

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: rgba(30, 40, 55, 0.95);
  border-radius: 12px;
  border: 2px solid rgba(255, 182, 193, 0.3);
  width: 90%;
  max-width: 800px;
  max-height: 80vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.modal-content.large {
  max-width: 1000px;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: rgba(255, 182, 193, 0.1);
  border-bottom: 1px solid rgba(255, 182, 193, 0.2);
}

.modal-header h3 {
  margin: 0;
  color: #FFB6C1;
}

.btn-close {
  background: none;
  border: none;
  color: #fff;
  font-size: 24px;
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
}

.modal-body {
  flex: 1;
  overflow: auto;
  padding: 20px;
}

.detail-section {
  margin-bottom: 25px;
}

.detail-section h4 {
  color: #FFB6C1;
  margin-bottom: 15px;
  font-size: 16px;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 15px;
}

.info-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 12px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
}

.info-item .label {
  color: rgba(255, 255, 255, 0.5);
  font-size: 12px;
}

.info-item .value {
  color: #FFB6C1;
  font-weight: 600;
  font-size: 14px;
}

.output-text {
  background: #0a0e1a;
  padding: 15px;
  border-radius: 6px;
  border: 1px solid rgba(255, 182, 193, 0.2);
  color: #87CEEB;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 13px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 400px;
  overflow-y: auto;
}

.output-text.error {
  color: #FF4655;
  border-color: rgba(255, 70, 85, 0.3);
}
</style>
